/*****************************************************************************
 *
 * Weber State University
 * CS4280 Spring 2010
 * Final Group Assignment
 *
 *
 *   TTTTTT                               CCCCC
 *     TT   EEEEE   A    M   M          CC      C
 *     TT   E      A A   M   M         CC   
 *     TT   E     A   A  MM MM  -----  CC
 *     TT   EEE   AAAAA  M M M  -----  CC
 *     TT   E     A   A  M   M          CC      C
 *     TT   EEEEE A   A  M   M            CCCCC
 *
 *   Jared Pack ---- Jon Mann ---- Joshua Clayton
 *
 *
 * 
 *
 ****************************************************************************/

 /* FILENAME winmain.cpp
  *
  * Change control Section
  *      
  * Team Member: Jon Mann
  * Version: 0.1
  * Date: 04/7/2010
  *     Added keyboard functions for jumping, shooting, and a forward sprint, 
  *        as well as setting up the wasd keys for moving
  *        Rebuilt the mouse movement code int WndProc() to enable infinite yaw
  *        and all around better control
  *      
  * Team Member: Jon Mann
  * Version: 0.2
  * Date: 04/8/2010
  *     Added mouse control code for fullscreen option
  *      
  * Team Member: Jon Mann
  * Version: 0.3
  * Date: 04/10/2010
  *        Added ToggleCursor() to enable cursor to move out of window
  *        Added keyboard input and set mouse control to work with cursor setup
  *
  * Team Member: Jon Mann
  * Version: 0.4
  * Date: 04/11/2010
  *        Rewrote the starting message to reflect the changes in controls and objectives
  *        Added code to enable jumping with the R mouse
  *
  * Team Member: Jon Mann
  * Version: 0.5
  * Date: 04/12/2010
  *        Added adjX and adjY variables as a short-term fix for the center-of-screen miscalculations
  */

/*****************************************************************************************************************
**
**    OpenGL Game Development
**    winmain.cpp
**
**    
**    Written by: Brian Rague
**    Date:        July 20, 2005
**
*****************************************************************************************************************/

#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#include<X11/Xlib.h>
#endif        

#include <cstdio>
#include <GL/gl.h>
#include <GL/glu.h>

#include "OGLWindow.h"

using namespace std;

float xCenter;
float yCenter;

HINSTANCE hInstance;

OGLWindow * g_glRender = NULL;

#ifdef _WIN32
int Init_Window(HWND &hWnd, HGLRC &hRC, HDC hDC)
{
    int pixelFormat;

    PIXELFORMATDESCRIPTOR pfd =
    {   
        sizeof(PIXELFORMATDESCRIPTOR),  // size
            1,                          // version
            PFD_SUPPORT_OPENGL |        // OpenGL window
            PFD_DRAW_TO_WINDOW |        // render to window
            PFD_DOUBLEBUFFER,           // support double-buffering
            PFD_TYPE_RGBA,              // color type
            32,                         // prefered color depth
            0, 0, 0, 0, 0, 0,           // color bits (ignored)
            0,                          // no alpha buffer
            0,                          // alpha bits (ignored)
            0,                          // no accumulation buffer
            0, 0, 0, 0,                 // accum bits (ignored)
            16,                         // depth buffer
            0,                          // no stencil buffer
            0,                          // no auxiliary buffers
            PFD_MAIN_PLANE,             // main layer
            0,                          // reserved
            0, 0, 0,                    // no layer, visible, damage masks
    };

    hDC = GetDC(hWnd);
    pixelFormat = ChoosePixelFormat(hDC, &pfd);
    SetPixelFormat(hDC, pixelFormat, &pfd);
    hRC = wglCreateContext(hDC);
    wglMakeCurrent(hDC, hRC);
    return 0;
}
#endif        

#ifdef _WIN32
/* WndProc *******************************************************************************************************/
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    static HGLRC hRC;
    static HDC hDC;
    int height, width;

    switch (msg)
    {
    case WM_CREATE:
            return Init_Window(hWnd, hRC, hDC);

    case WM_DESTROY:
    case WM_CLOSE:
    case WM_QUIT:
        wglMakeCurrent(hDC, NULL);
        wglDeleteContext(hRC);
        //PostQuitMessage(0);
        //Use the following instead of PostQuitMessage(0) which
        //does not work on Asus
        PostMessage(hWnd, WM_QUIT, 0, 0);
        return 0;

    case WM_SIZE:
        height = HIWORD(lParam);
        width = LOWORD(lParam);
        g_glRender->SetupProjection(width, height);
        return 0;

    case WM_KEYDOWN:
        int fwKeys;
        LPARAM keyData;

        fwKeys = (int)wParam;
        keyData = lParam;

        switch(fwKeys)
        {
        case VK_ESCAPE:
            wglMakeCurrent(hDC, NULL);
            wglDeleteContext(hRC);
            PostMessage(hWnd, WM_QUIT, 0, 0);
            break;
        default:
            // Begin - Phase 9
            g_glRender->OnKeyDown((GLuint)wParam);
            // End - Phase 9
            break;
        }

        return 0;
        //Begin - Phase 6
    case WM_MOUSEMOVE:
        // captures screen coordinates, not window coordinates
        g_glRender->OnMouseMove(LOWORD(lParam), HIWORD(lParam));
        return 0;
    case WM_LBUTTONDOWN:        // left mouse button
        g_glRender->OnMouseDownL(LOWORD(lParam), HIWORD(lParam));
        break;
    case WM_RBUTTONDOWN:        // right mouse button
        g_glRender->OnMouseDownR(LOWORD(lParam), HIWORD(lParam));
        break;

    default:
        break;
    }
    return (DefWindowProc(hWnd, msg, wParam, lParam));
}
#endif        

#ifdef _WIN32
int WINAPI WinMain (HINSTANCE hI, HINSTANCE hPrevious, LPSTR lpCmdString, int CmdShow)
#else
int main(int argc, char **argv)
#endif
{
bool exiting = false;
bool isCursorVis = false;
long windowWidth = 800;
long windowHeight = 600;
long windowBits = 32; //OGLWindow.depth
bool fullscreen = false;
#ifdef _WIN32
hInstance = hI;
MSG msg;
#endif
    // New Phase 3
    char str[700];

    g_glRender = new OGLWindow;

    // Start - Phase 3
    sprintf(str, "Welcome team C's Shooter Game!\n\n"
                 "Keys:\n<W> - Forward\n"
                 "<S> - Backward\n"
                 "<A> - Left Strafe\n"
                 "<D> - Right Strafe\n"
				 "<Shift> - Sprint forward\n\n"
                 "<C> - Release the cursor\n"
                 "<Y> - Invert mouse look\n"
                 "<N> - Near-God mode\n\n"
                 "<CTRL or Left mouse button> - Fires rockets\n"
				 "<SPACE or Right mouse button> - Jumps\n"
                 "Move mouse to look around.\n\n"
                 "Numpad '+' - Increase mouse sensitivity\n"
                 "Numpad '-' - Decrease mouse sensitivity\n\n"
                 "Created for WSU CS4280\nby Brian Rague.\n");
        
#ifdef _WIN32                
    MessageBox(NULL, str, "Welcome!", MB_OK);
#endif        

    sprintf(str, "Survival Shooter Game\n\n\n"
                 "Kill as many of the oncoming horde as long as you can! "
                 "If they hit you, you're dead.\n"
                 "By the way, every enemy killed comes back faster "
                 "than he was before. Kill as many as you can..."
                 "and good luck!");
#ifdef _WIN32        
    MessageBox(NULL, str, "Welcome!", MB_OK);
#endif        

#ifdef _WIN32
    if (MessageBox(NULL, "By default, we run in 800x600x32 mode, "
                   "would you like to run in fullscreen with current resolution?",
                   "Fullscreen?", MB_YESNO) == IDYES)
	{
        //fullscreen = true;
		windowWidth = GetSystemMetrics(SM_CXSCREEN);
		windowHeight = GetSystemMetrics(SM_CYSCREEN);
	}
    else
        fullscreen = false;
#endif                
    g_glRender->createGLWindow("blah blah", windowWidth,
                               windowHeight, fullscreen);
    g_glRender->Init();

    while (1)
    {
        // Phase 17 - change lists or Prepare and Render calls
        g_glRender->Prepare();
        g_glRender->Render();
        // Phase 17 - End
#ifdef __linux__
        if(g_glRender->Xevent_loop() == BUTTON_QUIT)
	{
		break;
	}
#endif        
#ifdef _WIN32

        if (PeekMessage (&msg, g_glRender->hwnd, 0, 0, PM_REMOVE))
        {
            
            TranslateMessage(&msg);
            DispatchMessage (&msg);
            if (msg.message == WM_QUIT) 
                break;
            
        }
#endif        
    }
    // Begin - Phase 5
    g_glRender->Shutdown();
    delete g_glRender;

#ifdef _WIN32
    return static_cast<int>(msg.wParam);
#else
    return 0;
#endif        
}
